package com.own.sign.socket;

import com.own.sign.config.WebSocketConfig;
import com.own.sign.constant.WebSocketConstant;
import net.sf.json.JSONObject;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

/**
 * WebSocket 处理器
 * @author liujiacheng
 */
@Service("webSocketClientHandle")
public class WebSocketClientHandle {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketClientHandle.class);

    /**
     * 依赖配置
     */
    @Autowired
    private WebSocketConfig webSocketConfig;
    /**
     * 保存WebSocket链接
     */
    private Map<String, WebSocketClient> clientMap = new HashMap<>();

    /**
     * 向WebSocket发送消息
     * @param key         用来区分消息
     * @param message
     * @param webCallback
     */
    public void send(final String key, final String message, final WebCallback webCallback) {

        WebSocketClient client = clientMap.get(webSocketConfig.getUrl());

        JSONObject json = new JSONObject();
        json.put("_method","cus-sec_SpcSignDataAsPEM");
        json.put("_id",1);

        if (client != null && client.isConnecting() && client.isOpen()) {

            /*String strSendData = "{\"_method\":\"cus-sec_SpcSignDataAsPEM\",\"_id\":1,\"args\":{\"inData\":\""
                    + message + "\",\"passwd\":\"88888888\"}}";*/

            JSONObject inDataJson = new JSONObject();
            inDataJson.put("inData",message);
            inDataJson.put("passwd","88888888");
            json.put("args",inDataJson.toString());
            String strSendData = json.toString();

            LOGGER.info("发送报文:{}",strSendData);
            client.send(strSendData);
        } else {
            try {
                client = new WebSocketClient(new URI(webSocketConfig.getUrl())) {

                    @Override
                    public void onOpen(ServerHandshake serverHandshake) {
                        LOGGER.info("==============打开链接==============");
                    }

                    @Override
                    public void onMessage(String arg) {
                        if (webCallback != null) {
                            webCallback.message(key, arg);
                        }
                    }

                    @Override
                    public void onError(Exception ex) {
                        if (webCallback != null) {
                            webCallback.error(ex);
                        }
                    }

                    @Override
                    public void onClose(int arg0, String arg1, boolean arg2) {
                        LOGGER.info("==============关闭链接==============");
                    }

                    @Override
                    public void onMessage(ByteBuffer bytes) {
                        try {
                            if (webCallback != null) {
                                webCallback.message(key, new String(bytes.array(), "utf-8"));
                            }
                        } catch (UnsupportedEncodingException e) {
                            LOGGER.error("处理返回信息异常-{}", e);
                        }
                    }
                };

                client.connect();
                Integer count = 0;
                // 阻塞等待OPEN
                while (!client.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
                    try {
                        count += WebSocketConstant.TIME_STEP;
                        Thread.sleep(WebSocketConstant.TIME_STEP);
                        if (count >= WebSocketConstant.TIME_OUT) {
                            webCallback.error(new Exception("WS服务器连接超时！或服务器已经关闭"));
                            break;
                        }
                    } catch (InterruptedException e) {
                        LOGGER.error("发送信息异常-{}", e);
                    }
                }

                /*String strSendData = "{\"_method\":\"cus-sec_SpcSignDataAsPEM\",\"_id\":1,\"args\":{\"inData\":\""
                        + message + "\",\"passwd\":\"88888888\"}}";*/

                JSONObject inDataJson = new JSONObject();
                inDataJson.put("inData",message);
                inDataJson.put("passwd","88888888");
                json.put("args",inDataJson.toString());

                String strSendData = json.toString();

                LOGGER.info("发送报文:{}",strSendData);

                client.send(strSendData);
                // 放入缓存
                clientMap.put(webSocketConfig.getUrl(), client);
            } catch (URISyntaxException e) {
                LOGGER.error("发送信息异常-{}", e);
            }
        }
    }
}
